package com.net128.beatportapps;

import java.io.IOException;
import java.io.InputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class TrackDataAccessor {
	private final static Logger log=Logger.getLogger(TrackDataAccessor.class);
	private final static int PAGE_SIZE=50;
	private DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd");
	private List<TrackData> trackDataList=new ArrayList<TrackData>();
	
	private int collectTracks(InputStream is) 
			throws ParserConfigurationException, SAXException, 
				IOException, XPathExpressionException, ParseException {
		DocumentBuilderFactory docfactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docbuilder = docfactory.newDocumentBuilder();
		Document docroot = docbuilder.parse(is);
		XPath xpath = XPathFactory.newInstance().newXPath();
		int total=((Double)xpath.evaluate("//result/@resultCount", docroot, XPathConstants.NUMBER)).intValue();
		NodeList trackList = (NodeList) xpath.evaluate("//track", docroot, XPathConstants.NODESET);
			
		int n=trackList.getLength();
		for(int i=0;i<n;i++) {
			Element track = (Element) trackList.item(i);
			String id=track.getAttribute("id");//context.getValue("//track");
			String name=(String)xpath.evaluate("name", track, XPathConstants.STRING);
			Date dateAdded=dateFormat.parse((String)xpath.evaluate("dateAdded", track, XPathConstants.STRING));
			Date dateReleased=dateFormat.parse((String)xpath.evaluate("dateReleased", track, XPathConstants.STRING));
			String mixName=(String)xpath.evaluate("mixName", track, XPathConstants.STRING);
			if("Original Mix".equals(mixName)) {
				mixName="";
			} else if(mixName.length()>0){
				mixName=" ("+mixName+")";
			}
			mixName=mixName.replaceAll(", ", "+");
			String labelName=(String)xpath.evaluate("label/name", track, XPathConstants.STRING);
			NodeList artistList = (NodeList)xpath.evaluate("performer[@ref='Artist']", track, XPathConstants.NODESET);
			Element artist = (Element) artistList.item(0);
			String artistName=artist.getTextContent();
			for(int j=1;j<artistList.getLength();j++) {
				artist = (Element) artistList.item(0);
				artistName+="+"+artist.getTextContent();
			}
			TrackData trackData=new TrackData(id, artistName, name, 
					mixName, dateAdded, dateReleased, labelName, null, null, 0);	
			log.info(trackData);
			trackDataList.add(trackData);
		}
		
		return total-trackDataList.size();
	}
	
	private void run(String user, String password) throws Exception {
		String base="://www.beatport.com/en-US/";
		String loginUrl="https"+base+"html/account/authentication/crm_login";
		loginUrl+="?username="+user+"&password="+password;
		String dlTrackInfoUrlBase="http"+base+"xml/user/downloads/downloaded?resultsPerPage="+
			PAGE_SIZE+"&pageNumber=";
		HttpClient httpclient = new HttpClient();
		
		GetMethod httpget = new GetMethod(loginUrl);
		try {
			log.info("Logging in into beatport");
			httpclient.executeMethod(httpget);
			if(httpget.getStatusCode()==200) {
				Cookie [] cookies=httpclient.getState().getCookies();
				for(int i=0;i<cookies.length;i++) {
					Cookie cookie=cookies[i];
					log.info(cookie.getDomain()+" "+cookie.getName()+" "+cookie.getPath()+" "+cookie.getValue());
				}
				httpget.releaseConnection();
				log.info("Login successful");
				int i=1;
				int nTrackRecordsRemaining=-1;
				do {
					String dlTrackInfoUrl=dlTrackInfoUrlBase+(i++);
					log.info("Request: "+dlTrackInfoUrl);
					httpget=new GetMethod(dlTrackInfoUrl);
					httpclient.executeMethod(httpget);
					if(httpget.getStatusCode()==200) {
						nTrackRecordsRemaining=collectTracks(httpget.getResponseBodyAsStream());
						log.info(nTrackRecordsRemaining+" track records remaining");
					} else {
						nTrackRecordsRemaining=0;
					}
					httpget.releaseConnection();
				} while(nTrackRecordsRemaining>0);
			}		
		} finally {
			httpget.releaseConnection();
		}
	}

	public static void main(String[] args) throws Exception {
		if(args.length<2) {
			log.error("Usage: "+TrackDataAccessor.class.getName()+" user password");
		} else {
			new TrackDataAccessor().run(args[0], args[1]);
		}
	}
}
